﻿using System;
using System.Configuration;
using System.Diagnostics;
using System.Net.Mail;
using AzureQueue;
using Microsoft.WindowsAzure.StorageClient;
using ThreadedWorkerRoleLib;

namespace MultiThreadedWorkerRole
{
    public class EmailWorker : WorkerEntryPoint
    {
        readonly int NumberOfSendEmailRetries;

        public EmailWorker()
        {
            NumberOfSendEmailRetries = int.Parse(ConfigurationManager.AppSettings["NumberOfSendEmailRetries"]);
        }

        void SendEmail(EmailEntity email)
        {
            Debug.WriteLine("Sending e-mail to '{0}', subject={1}, body={2}", email.To, email.Subject, email.Body);

            var mailMessage = new MailMessage { From = new MailAddress(email.From) };
            mailMessage.To.Add(new MailAddress(email.To));
            mailMessage.Subject = email.Subject;
            mailMessage.Body = email.Body;
            mailMessage.IsBodyHtml = true;

            // Send the email
            new SmtpClient().Send(mailMessage);
        }

        void ProcessEmail(EmailEntity email, CloudQueueMessage queueMessage)
        {
            SendEmail(email);
            QueuDataSource.DeleteEmail(queueMessage);            
        }

        bool GetNextEmailFromQueue(out EmailEntity email, out CloudQueueMessage queueMessage)
        {
            // Try to send the e-mail NumberOfSendEmailRetries times, if all attempts fails then leave the e-mail in the queue for auditing reasons
            return QueuDataSource.GetEmail(out email, out queueMessage) 
                && queueMessage.DequeueCount < NumberOfSendEmailRetries
            ;
        }

        /// <summary>
        /// Processes the next item in the queue
        /// </summary>
        /// <returns>Returns true if there was processed an item</returns>
        bool ProcessItem()
        {
            Debug.WriteLine("Starting to process a single e-mail message");
            Debug.Indent();

            EmailEntity email;
            CloudQueueMessage queueMessage;
            var result = GetNextEmailFromQueue(out email, out queueMessage);

            if (result) ProcessEmail(email, queueMessage);

            Debug.Unindent();
            Debug.WriteLine("Done processing a single e-mail message with, result={0}", result);

            return result;
        }

        protected override int ProcessItems()
        {
            Debug.WriteLine("Starting to process the e-mail queue");
            Debug.Indent();

            var numberOfProcessedEmails = 0;
            var itemsInTheQueue = true ;

            do
                try
                {
                    itemsInTheQueue = ProcessItem();
                    numberOfProcessedEmails += Convert.ToInt32(itemsInTheQueue);
                }
                catch (Exception exception)
                {
                    Trace.TraceError("E-mail queue processing exception: {0}", exception.ToString());
                } 
            while (itemsInTheQueue);

            Debug.Unindent();
            Debug.WriteLine("Done to processing the e-mail queue, {0} e-mail's was sent", numberOfProcessedEmails);

            return numberOfProcessedEmails;
        }

    }
}
